<template>
<div class="uploading">
    <a-col :span="3">
        <a-tabs default-active-key="1" tab-position="left" :style="{ height: '200px' }" @change="tab_change" v-model="activeKey">
            <a-tab-pane key="1" >
                <span slot="tab">
                    <a-icon type="upload" />
                    正在上传 {{beUploadsFiles.length}}
                </span>
            </a-tab-pane>
            <a-tab-pane key="2">
                <span slot="tab">
                    <a-icon type="close-circle" theme="twoTone" two-tone-color="#f81d22" />
                    传输失败  {{errorUploadsFiles.length}}
                </span>
            </a-tab-pane>
            <a-tab-pane key="3">
                <span slot="tab">
                    <a-icon type="check-circle" theme="twoTone" two-tone-color="#52c41a" />
                    传输完成  {{sucessUploadsFiles.length}}
                </span>
            </a-tab-pane>
        </a-tabs>
      </a-col>
      <a-col :span="20" v-show="activeKey==1">
        <a-row>
            <div style="width: 100%;">
                <span>上传总进度:</span>
                <!-- style="min-width: 500px;" -->
                <a-progress :percent="all_size==0?0:Number((upload_size / all_size * 100).toFixed(0))" style="width: 75%;margin: 5px;"/>
                <a-button   class="dashed_none" size="small" @click="upload_files" style="margin-left: 10px;">全部开始</a-button>
                <a-button   class="dashed_none" size="small">全部取消</a-button>
                <a-tooltip placement="topLeft">
                    <template slot="title">
                        <span>设置</span>
                    </template>
                    <a-button  icon="setting"  class="border_none"/> 
                </a-tooltip>
            </div>
            <a-space  class="space_item" style="width: 100%;">
               
            </a-space>
        </a-row>
        <a-row style="margin-top: 5px;" >
            <a-table 
            :columns="uploading_columns" 
            :data-source="beUploadsFiles"
            :pagination="uploading_pagination"
            size="small"
            class="m-manager-table__table m-manager-table__hover--none m-manager-table__choose--none"
            tableLayout="auto" 
            bordered
            style="min-height:500px"
            :showHeader="false"
            rowKey="fuid"
            >
            <template slot="nameSize" slot-scope="text, record">
                <div >
                    <a-space  class="space_item">
                        <div>
                            <a-icon type="file" theme="twoTone" />
                        </div>
                        <div style="margin-left: 10px;">
                            <a-row>
                            <div >{{ record.file.name }}</div>
                            </a-row>
                            <a-row>
                                <div >{{ record.file.size>0?FormatFileSize(record.file.size):"-"}}</div>
                            </a-row>
                        </div>
                    </a-space>
                </div>
            </template>
            <!-- 0其他提示信息  1队列中 2分割文件并计算md5   3分割文件 3uploading 4 sucess 5 error -->
            <template slot="time_left" slot-scope="text, record">
                <span>{{ (record.status.status==0 ||record.status.status==1 ||record.status.status==2)?"--": record.status.time_left}}</span>
            </template>
            <template slot="status" slot-scope="text, record">
                <a-row>
                    <a-space>
                        <a-badge status="default" :text="record.status.message"  v-show="record.status.status==1"/>
                        <a-badge status="processing" :text="record.status.message" v-show="record.status.status==0 ||record.status.status==2 || record.status.status==3" />
                        <a-progress style="width:300px" :percent="record.status.percentage" status="active" v-show="(record.status.status==2 ||record.status.status==0) && record.status.percentage>0"/>
                        <a-progress style="width:300px" :percent="record.status.percentage" status="active" v-show="record.status.status==3"/>
                    </a-space>
                </a-row>
                <a-row>
                    <a-space>
                        <span v-show="record.status.status==3">{{record.speed}}</span>
                    </a-space>
                </a-row>
            </template>
            <template slot="operation" slot-scope="text, record">
                <template slot="operation" slot-scope="text, record">
                    <a-popconfirm  title="Sure to delete this file?" @confirm="() =>retry_delete(record)">
                        <a href="javascript:;">删除</a>
                    </a-popconfirm>
                </template>
                <a-space  class="space_item">
                    <div class="hover_tool">
                        <a-tooltip placement="topLeft" >
                            <template slot="title">
                                <span>开始/暂停</span>
                            </template>
                            <a-icon type="caret-right"  />
                        </a-tooltip>
                    </div>
                    <div class="hover_tool">
                        <a-tooltip placement="topLeft" class="hover_tool">
                            <template slot="title">
                                <span>取消上传</span>
                            </template>
                            <a-icon type="close" />
                        </a-tooltip>
                    </div>
                </a-space>
            </template>
        </a-table>
        </a-row>
      </a-col>
      <a-col :span="20" v-show="activeKey==2">
            <div >
        <a-row>
            <div class="ant-breadcrumb">
                <a-space  class="space_item">
                    <a-button   class="dashed_none" size="small" :disabled="errorUploadsFiles.lengt==0" @click="reupload_error_records"><a-icon type="share-alt" />重新上传</a-button>
                    <a-button   class="dashed_none" size="small" :disabled="errorUploadsFiles.length==0" @click="delete_error_records"><a-icon type="share-alt" />删除记录</a-button>
                </a-space>
            </div>
        </a-row>
        <a-divider />
        <a-row>
            <a-table 
                :columns="error_columns" 
                :data-source="errorUploadsFiles"
                :pagination="error_pagination"
                size="small"
                class="myfile-table"
                tableLayout="auto"
                bordered
                rowKey="fuid"
                >
                <template slot="name" slot-scope="text, record">
                    <div >{{ record.file.name}}</div>
                </template>
                <template slot="error_msg" slot-scope="text, record">
                    {{record.status.message}}
                </template>
            </a-table>
        
        </a-row>
    </div>
      </a-col>
      <a-col :span="20" v-show="activeKey==3">
            <div >
                <a-row>
                    <div class="ant-breadcrumb">
                        <a-space  class="space_item">
                            <a-button   class="dashed_none" size="small" :disabled="sucessUploadsFiles.length==0" @click="delete_sucess_records"><a-icon type="share-alt" />删除记录</a-button>
                        </a-space>
                    </div>
                </a-row>
                <a-divider />
                <a-row>
                    <a-table 
                        :columns="sucess_columns" 
                        :data-source="sucessUploadsFiles"
                        :pagination="sucess_pagination"
                        size="small"
                        class="myfile-table"
                        tableLayout="auto"
                        bordered
                        rowKey="fuid"
                        >
                        <template slot="name" slot-scope="text, record">
                            <div >{{ record.file.name}}</div>
                        </template>
                        <template slot="pre_dir" slot-scope="text, record">
                            {{record.rootdir}}
                        </template>
                        <template slot="size" slot-scope="text, record">
                            {{ record.file.size>0?FormatFileSize(record.file.size):"-"}} 
                        </template>
                    </a-table>
                </a-row>
            </div>
      </a-col>
</div>
</template>
<script>
    const uploading_columns = [
        {
            dataIndex: 'name',
            key: 'file.name',
            scopedSlots: { customRender: 'nameSize' } ,
            width:300,
        },
        {
            scopedSlots: { customRender: 'time_left' } ,
            width:50,
        },
        {
            scopedSlots: { customRender: 'status' } ,
            width:350,
        },
        {
            scopedSlots: { customRender: 'operation' } ,
            width:40,
        },
    ];
    const uploading_pagination ={
        size:'small',
        pageSize:10,
        showTotal:(total, range)=>{
            return `共 ${total} 个,当前${range[0]}-${range[1]}`
        }
    }
    const sucess_columns=[
        { 
            title: '文件',
            scopedSlots: { customRender: 'name' } ,
            width:150,
            align:'center'
        },
        {
            title: '目录',
            key: 'pre_dir',
            scopedSlots: { customRender: 'pre_dir' },
            align:'center'
        },
        {
            title: '大小',
            key: 'size',
            scopedSlots: { customRender: 'size' },
            align:'center'
        },
    ]
    const sucess_pagination ={
        size:'small',
        pageSize:10,
        showTotal:(total, range)=>{
            return `共 ${total} 个，当前${range[0]}-${range[1]}`
        }
    }
    const error_columns=[
        { 
            title: '文件',
            scopedSlots: { customRender: 'name' } ,
            width:150,
            align:'center'
        },
        {
            title: '错误信息',
            scopedSlots: { customRender: 'error_msg' },
            align:'center'
        },
    ]
    const error_pagination ={
        size:'small',
        pageSize:10,
        showTotal:(total, range)=>{
            return `共 ${total} 个，当前${range[0]}-${range[1]}`
        }
    }
    export default {
        data() {
            return {
                beUploadsFiles: [],
                sucessUploadsFiles:[],
                errorUploadsFiles:[],

                uploading_pagination,
                uploading_columns,

                sucess_columns,
                sucess_pagination,

                error_columns,
                error_pagination,

                work_url:'https://nmgwxyy.cn/alatan/static/uploads_worker.js',
                workers:[],
                upload_status:false,
                multi:3,//多线程上传个数
                worker_textContent:"",

                all_size:0,
                upload_size:0,
                activeKey:"1",
            }
        },
        beforeUnmount() {
            this.$mitt.off('add_files');
        },
        mounted() {
            fetch(this.work_url,{ method:"GET",})
            .then((response) =>  response.text())
            .then((textContent) => {
                this.worker_textContent=textContent
            })
            this.$mitt.on("add_files",(_beUploadsFiles)=>{
                _beUploadsFiles.forEach((_beUploadsFile)=>{
                    this.all_size=this.all_size+_beUploadsFile.file.size
                    this.beUploadsFiles.push(_beUploadsFile)
                })
                this.upload_files();
            })   
        },
        computed: {
        },
        methods:{
            // 0其他提示信息  1队列中 2分割文件并计算md5   3分割文件 3uploading 4 sucess 5 error
            creatWorkers(){
                let blob = new Blob([this.worker_textContent]);
                //创建worker
                for (let index = 0; index < this.multi; index++) {
                    let worker=new Worker(URL.createObjectURL(blob))
                    worker.onmessage =this.worker_get_message
                    this.workers.push({
                        worker:worker,
                        uuid:this.Uuid(),
                        file_key:"",
                        free:true,
                        enable:true,//是否需要删除
                    })
                }
                //销毁worker 等该worker已经完成任务后在销毁 或停止worker中的任务
                for (let index = this.multi; index < this.workers.length; index++) {
                    this.workers[index].enable=false;
                }
            },
            deleteWorkers(){
                // for (let index = 0; index < this.workers.length; index++) {
                //     this.workers[index].enable=false;
                // }
            },
            changg_worker(){
                this.creatWorkers();
            },
            worker_get_message(e){
                let {workid,status}=e.data
                let _file_find=this.GetFileByUuid(workid)
                _file_find.status=status
                let beUploadsFile_index=this.GetFileIndexByUuid(workid)
                if(status.post_size){
                    this.upload_size=this.upload_size+status.post_size
                    let _fileOb=this.beUploadsFiles[beUploadsFile_index]
                    if(!_fileOb.upload_size){
                        _fileOb.upload_size=0
                    }
                    _fileOb.upload_size=_fileOb.upload_size+status.post_size
                    let lst_time=_fileOb.lst_time
                    let now_time=new Date().getTime()
                    if(lst_time){
                        _fileOb.speed=(status.post_size*1000/(now_time-lst_time)/1024/1024).toFixed(2)+"M/s";
                    }
                    _fileOb.lst_time=now_time
                }
                if(status.status==5 ||status.status==4){
                    if(status.end==true){
                        if(beUploadsFile_index>=0){
                            let _fileObs=this.beUploadsFiles.splice(beUploadsFile_index,1)
                            this.SetWorkderFree(workid);//其实workid是worker_index
                            if(status.status==5 ){ //错误的
                                this.errorUploadsFiles.push(_fileObs[0])
                            }
                            else if(status.status==4 ){ //成功的
                                this.sucessUploadsFiles.push(_fileObs[0])
                            }
                            this.upload_files()
                            
                        }
                    }
                }
            },
            upload_files(){
                if(this.workers.length==0){
                    this.creatWorkers();
                }
                
                if(this.beUploadsFiles.length==0 ){
                    let _worker_find=this.GetWorkderProcess()
                    if(_worker_find){

                    }
                    else{
                        console.log("all files upload end...")
                        this.all_size=0
                        this.upload_size=0
                    }
                }
                //w.terminate ? w.terminate() : ''
                else{
                    let _worker_find=this.GetWorkderFree()
                    let _file_find=this.GetFilesbeUpload()
                    while(_worker_find && _file_find){
                        this.DoNext(_worker_find,_file_find)
                        _worker_find=this.GetWorkderFree()
                        _file_find=this.GetFilesbeUpload()
                    }
                }
            },
            GetWorkderProcess(){
                return this.workers.find((val)=>{
                    return val.free==false && val.enable==true
                })
            },
            GetWorkderFree(){
                return this.workers.find((val)=>{
                    return val.free==true && val.enable==true
                })
            },
            GetFilesbeUpload(){
                return this.beUploadsFiles.find((val)=>{
                    return val.status.status==1
                })
            },
            GetWorkderByUuid(_Uuid){
                return this.workers.find((val)=>{
                    return val.uuid==_Uuid
                })
            },
            GetFileByUuid(_Uuid){
                return this.beUploadsFiles.find((val)=>{
                    return val.uuid==_Uuid
                })
            },
            GetFileIndexByUuid(_Uuid){
                return this.beUploadsFiles.findIndex((val)=>{
                    return val.uuid==_Uuid
                })
            },
            SetWorkderProcess(_Uuid){
                let _worker_find=this.GetWorkderByUuid(_Uuid)
                if(_worker_find){
                    _worker_find.free=false
                }
            },
            SetWorkderFree(_Uuid){
                let _worker_find=this.GetWorkderByUuid(_Uuid)
                if(_worker_find){
                    _worker_find.free=true
                }
            },
            DoNext(_worker_find,_file_find){
                _worker_find.free=false
                _file_find.status.status=2
                _file_find.uuid=_worker_find.uuid
                this.postMessage(_worker_find,_file_find);
            },
            postMessage(_worker_find,_file_find,operation="start"){
                let _Message={
                    file:_file_find.file,
                    workid: _worker_find.uuid,
                    token:this.$store.state.user.token,
                    type:'single',//single multy
                    rootdir:_file_find.rootdir,
                    usemd5:false,
                    operation,
                }
                _worker_find.worker.postMessage(_Message)
            },
            start_pause_stop_operation(_val,operation="start"){ //start pause stop
                let uuid=_val.uuid
                let _worker_find=this.GetWorkderByUuid(uuid)
                if(_worker_find){
                    _worker_find.worker.postMessage({
                        workid: _worker_find.uuid,
                        operation:"pause",
                    })
                }
            },
            share_Confirm(records,share=true){
                this.$confirm({
                    title: `你是否需要${share?'共享':'取消共享'}选择的文件?`,
                    content: `当你选择确定后,其他人${share?'':'不再'}能够访问并下载您共享的文件。`,
                    cancelText:"取消",
                    okText:"确定",
                    onOk() {
                        return new Promise((resolve, reject) => {
                            //根据文件的数据库id去修改
                            setTimeout(Math.random() > 0.5 ? resolve : reject, 1000);
                        }).catch(() => console.log('Oops errors!'));
                    },
                    onCancel() {},
                });
            },
            delete_Confirm(records){
                this.$confirm({
                    title: `你是否需要删除选择的文件?`,
                    content: `当你选择确定后,共享的文件不再共享并将永久删除,请慎重。`,
                    cancelText:"取消",
                    okText:"确定",
                    onOk() {
                        return new Promise((resolve, reject) => {
                            //根据文件的数据库id去修改
                            setTimeout(Math.random() > 0.5 ? resolve : reject, 1000);
                        }).catch(() => console.log('Oops errors!'));
                    },
                    onCancel() {},
                });
            },
            delete_sucess_records(){
                this.sucessUploadsFiles=[]
            },
            delete_error_records(){
                this.errorUploadsFiles=[]
            },
            reupload_error_records(){
                for (let index = 0; index < this.errorUploadsFiles.length; index++) {
                    let record = this.errorUploadsFiles[index];
                    record.status={
                        status:1,
                        message:'队列中',
                        percentage:0
                    }
                    this.beUploadsFiles.push(record)
                }
                this.errorUploadsFiles=[]
            },
            compute_hash(one_file){
                return new Promise((resolve)=>{
                    var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
                    file = one_file.file,
                    chunkSize = 2 * 1024 * 1024,                             // Read in chunks of 2MB
                    chunks = Math.ceil(file.size / chunkSize),
                    currentChunk = 0,
                    spark = new SparkMD5.ArrayBuffer(),
                    fileReader = new FileReader();
                    fileReader.onload = function (e) {
                        console.log('read chunk nr', currentChunk + 1, 'of', chunks);
                        spark.append(e.target.result);                   // Append array buffer
                        currentChunk++;
                        if (currentChunk < chunks) {
                            console.info(currentChunk, chunks);
                            one_file.status.percentage=Number(((currentChunk) / chunks * 100).toFixed(0))
                            loadNext();
                        } else {
                                console.log('finished loading');
                                let endMDB=spark.end()
                                console.info('computed hash', spark.end());  // Compute hash
                                one_file.key=endMDB
                                one_file.status={
                                status:1,
                                message:'队列中',
                                percentage:0
                            }
                            resolve(endMDB) 
                            
                        }
                    };
                    fileReader.onerror = function () {
                        console.warn('oops, something went wrong.');
                        resolve(false) 
                    };
                    function loadNext() {
                        var start = currentChunk * chunkSize,
                            end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
                        fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
                    }
                    loadNext()
                })
            },
            tab_change(acKey){
                console.log(acKey)
            },
        }
    }
</script>
<style >
/* .hover_tool{

} */
</style>